package com.chapter10.innerclass_;

/**
 * 匿名内部类
 * 1.本质还是类 2.是一个内部类 3.该类没有名字
 * 匿名内部类是定义在外部类的局部位置上的，并且系统分配匿名内部类的名字
 * 基本语法为 new 类（接口）{}
 * */
public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer03 outer03 = new Outer03();
        outer03.method();

    }
}
class Outer03{
    private int n1 = 10;
    public void method(){
        //基于接口的匿名内部类
        //传统方式：如果要使用A接口，必须创建一个类去实现A接口，并创建对象
        //如果想要Tiger类只使用一次，后面不再使用，传统写法则会浪费资源
        //可以使用匿名内部类简化开发
        //a1的编译类型是A  ，a1的运行类型是匿名内部类
        /*
          底层：匿名内部类系统会在底层自动分配一个类名
             class Outer03$1 implements A{
                @Override
                public void cry() {
                    System.out.println("Tiger....");
             }
        */
        // jdk底层在创建匿名内部类时 Outer03$1 ，马上就创建了Outer03$1 实例，
        // 并把地址返回给a1
        // 匿名内部类使用一次就不能再使用了
        A a1 = new A(){
            @Override
            public void cry() {
                System.out.println("Tiger....");
            }
        };
        System.out.println("a1的运行类型是"+ a1.getClass());
        a1.cry();
        a1.cry();

        //演示基于类的匿名内部类
        //father的编译类型是Father
        //father的运行类型是Outer03$2
        /*
            底层是
            class Outer03$2 extends Father{

            }
        */
        Father father = new Father(){

            {
                System.out.println("Outer03$2代码块");
            }
            @Override
            public void test() {
                System.out.println("father...");
            }
        };
        father.test();
        System.out.println("father的运行类型是" + father.getClass());
    }

}
interface A{
    public void cry();
}
//class Tiger implements A{
//    @Override
//    public void cry() {
//        System.out.println("Tiger");
//    }
//}
class Father{
    public void test(){

    }
}